package cn.com.bluemoon.daps.system.service.impl;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.enums.BmStatus;
import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.common.exception.DapException;
import cn.com.bluemoon.daps.common.toolkit.AesEncryptUtils;
import cn.com.bluemoon.daps.system.entity.DapSystemDatasource;
import cn.com.bluemoon.daps.system.entity.DapSystemDatasourceEnvironment;
import cn.com.bluemoon.daps.system.mapper.DapSystemDatasourceEnvironmentMapper;
import cn.com.bluemoon.daps.system.service.DapSystemDatasourceEnvironmentService;
import cn.com.bluemoon.daps.system.utils.ConnectUtils;
import cn.com.bluemoon.dataserver.apitable.api.RemoteApiTableService;
import cn.com.bluemoon.dataserver.apitable.api.dto.DataSourceRequestDto;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DapSystemDatasourceEnvironmentServiceImpl extends ServiceImpl<DapSystemDatasourceEnvironmentMapper, DapSystemDatasourceEnvironment> implements DapSystemDatasourceEnvironmentService {

    @Resource
    DapSystemDatasourceEnvironmentMapper dapSystemDatasourceEnvironmentMapper;

    @Resource
    RemoteApiTableService remoteApiTableService;

    /**
     * 新增或修改数据源环境信息
     * @param environment
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultBean<String> updateOrInsertEnvironment(DapSystemDatasourceEnvironment environment, DapSystemDatasource dapSystemDatasource) {

        // 查询当前数据源是否存在环境
        List<DapSystemDatasourceEnvironment> dapSystemDatasourceEnvironments = this.dapSystemDatasourceEnvironmentMapper.selectList(new LambdaQueryWrapper<DapSystemDatasourceEnvironment>()
                .eq(DapSystemDatasourceEnvironment::getDatasourceId, environment.getDatasourceId())
                .eq(DapSystemDatasourceEnvironment::getBmStatus, BmStatus.ON.getCode())
                .eq(DapSystemDatasourceEnvironment::getEnvironment, environment.getEnvironment()));
        String name = environment.getEnvironment() == 1 ? "开发" : environment.getEnvironment() == 2 ? "测试" :
                environment.getEnvironment() == 3 ? "预发布" : "生产";
        Boolean flag = Objects.equals(environment.getExecutionEngine(), 2);
        // 1.筛选出独立源库的数据，2.筛选出impala引擎数据 3.筛选出环境信息
        List<DapSystemDatasourceEnvironment> list = dapSystemDatasourceEnvironments.stream().filter(d -> {
            return environment.getIsInfoResource() ? d.getIsInfoResource() : flag ? Objects.equals(d.getExecutionEngine(), 2)
                    : !d.getIsInfoResource() && null == d.getExecutionEngine();
        }).collect(Collectors.toList());
        if(!list.isEmpty()){
            Set<String> set = list.stream().map(DapSystemDatasourceEnvironment::getId).collect(Collectors.toSet());
            if(dapSystemDatasource.getDatabaseType().equals(DatabaseType.HIVE)){
                if(StringUtils.isBlank(environment.getId()) || !set.contains(environment.getId())){
                    String error = environment.getIsInfoResource() ? "的独立元库" :
                            Objects.equals(environment.getExecutionEngine(), 2) ? "的impala数据源" : "";
                    return ResultBean.error("当前数据源存在" + name + "环境" + error);
                }
            }else {
                if(StringUtils.isBlank(environment.getId())){// 新增
                    List<DapSystemDatasourceEnvironment> e = list.stream().filter(l -> l.getDatasourceRole() == environment.getDatasourceRole())
                            .collect(Collectors.toList());
                    if(!e.isEmpty()){
                        String error = environment.getDatasourceRole() == 1 ? "主库" : "从库";
                        return ResultBean.error("当前数据源存在" + name + "环境" + error);
                    }
                }else {
                    if(set.contains(environment.getId())){
                        List<DapSystemDatasourceEnvironment> collect = list.stream().filter(l -> l.getId().equals(environment.getId()) && l.getDatasourceRole() != environment.getDatasourceRole()).collect(Collectors.toList());
                        if(!collect.isEmpty() && set.size() > 1){
                            String error = environment.getDatasourceRole() == 1 ? "主库" : "从库";
                            return ResultBean.error("当前数据源存在" + name + "环境" + error);
                        }
                    }else {
                        return ResultBean.error("当前数据源与环境不匹配");
                    }
                }
            }
            // String id = list.stream().map(DapSystemDatasourceEnvironment::getId).collect(Collectors.joining());
            // 如果是新增数据源环境,变更数据源环境
           /* if(StringUtils.isBlank(environment.getId()) || !environment.getId().equals(id)){
                String error = environment.getIsInfoResource() ? "的独立元库" :
                        Objects.equals(environment.getExecutionEngine(), 2) ? "的impala数据源" : "";
                return ResultBean.error("当前数据源存在" + name + "环境" + error);
            }*/
        }
        // md5解密
        ResultBean<String> stringResultBean = ConnectUtils.decoderBase(environment.getPassword());
        if(stringResultBean.getCode() == 500){
            return stringResultBean;
        }
        // 对密码进行加密
        if(StringUtils.isBlank(stringResultBean.getContent())){
            environment.setPassword(null);
        }else{
            String encrypt = Optional.ofNullable(stringResultBean.getContent()).map(pwd -> {
                try {
                    return AesEncryptUtils.encrypt(pwd);
                } catch (Exception e) {
                    throw new DapException(e.getMessage());
                }
            }).orElse(null);
            environment.setPassword(encrypt);
        }
        // 修改
        boolean isEdit = environment.getId() != null;
        boolean update = this.saveOrUpdate(environment);
        if (update && isEdit) {
            DataSourceRequestDto dataSourceRequestDto = new DataSourceRequestDto();
            dataSourceRequestDto.setDataSourceId(environment.getDatasourceId());
            dataSourceRequestDto.setEnvVersion(environment.getEnvironment());
            ResultBean<Boolean> res = remoteApiTableService.dsRefresh(dataSourceRequestDto);
            log.info("刷新数据服务-取数数据源情况：{}", res);
        }
        return ResultBean.ok(environment.getId());
    }
}
